package org.altervista.cp.thinjdbc.wrappers;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.Ref;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;

public abstract class CallableStatement extends PreparedStatement implements
		java.sql.CallableStatement {

	static CallableStatement newInstance(CallableStatement cs, String sql) {
		CallableStatement csw = _GENERATOR.generate(cs);
		csw._sql = sql;
		return csw;
	}

	public void close() {
		try {
			java.sql.CallableStatement cs = _unwrap();
			if (cs != null) {
				cs.close();
			}
		} catch (SQLException e) {
			throw new SQLRuntimeException(e);
		} finally {
			_GENERATOR.release(this);
		}
	}

	public void setAsciiStream(String parameterName, InputStream x, int length) {
		new AsciiStreamParameter(parameterName, x, length).setParameter();
	}

	public void setBigDecimal(String parameterName, BigDecimal x) {
		new BigDecimalParameter(parameterName, x).setParameter();
	}

	public void setBinaryStream(String parameterName, InputStream x, int length) {
		new BinaryStreamParameter(parameterName, x, length).setParameter();
	}

	public void setBoolean(String parameterName, boolean x) {
		new BooleanParameter(parameterName, x).setParameter();
	}

	public void setByte(String parameterName, byte x) {
		new ByteParameter(parameterName, x).setParameter();
	}

	public void setBytes(String parameterName, byte[] x) {
		new BytesParameter(parameterName, x).setParameter();
	}

	public void setCharacterStream(String parameterName, Reader reader,
			int length) {
		new CharacterStreamParameter(parameterName, reader, length)
				.setParameter();
	}

	public void setDate(String parameterName, Date x, Calendar cal) {
		new DateParameter(parameterName, x, cal).setParameter();
	}

	public void setDate(String parameterName, Date x) {
		new DateParameter(parameterName, x).setParameter();
	}

	public void setDouble(String parameterName, double x) {
		new DoubleParameter(parameterName, x).setParameter();
	}

	public void setFloat(String parameterName, float x) {
		new FloatParameter(parameterName, x).setParameter();
	}

	public void setInt(String parameterName, int x) {
		new IntParameter(parameterName, x).setParameter();
	}

	public void setLong(String parameterName, long x) {
		new LongParameter(parameterName, x).setParameter();
	}

	public void setNull(String parameterName, int sqlType, String typeName) {
		new NullParameter(parameterName, sqlType, typeName).setParameter();
	}

	public void setNull(String parameterName, int sqlType) {
		new NullParameter(parameterName, sqlType).setParameter();
	}

	public void setObject(String parameterName, Object x, int targetSqlType,
			int scale) {
		new ObjectParameter(parameterName, x, targetSqlType, scale)
				.setParameter();
	}

	public void setObject(String parameterName, Object x, int targetSqlType) {
		new ObjectParameter(parameterName, x, targetSqlType).setParameter();
	}

	public void setObject(String parameterName, Object x) {
		new ObjectParameter(parameterName, x).setParameter();
	}

	public void setShort(String parameterName, short x) {
		new ShortParameter(parameterName, x).setParameter();
	}

	public void setString(String parameterName, String x) {
		new StringParameter(parameterName, x).setParameter();
	}

	public void setTime(String parameterName, Time x, Calendar cal) {
		new TimeParameter(parameterName, x, cal).setParameter();
	}

	public void setTime(String parameterName, Time x) {
		new TimeParameter(parameterName, x).setParameter();
	}

	public void setTimestamp(String parameterName, Timestamp x, Calendar cal) {
		new TimestampParameter(parameterName, x, cal).setParameter();
	}

	public void setTimestamp(String parameterName, Timestamp x) {
		new TimestampParameter(parameterName, x).setParameter();
	}

	public void setURL(String parameterName, URL val) {
		new URLParameter(parameterName, val).setParameter();
	}

	public abstract Array getArray(int i);

	public abstract Array getArray(String parameterName);

	public abstract BigDecimal getBigDecimal(int parameterIndex, int scale);

	public abstract BigDecimal getBigDecimal(int parameterIndex);

	public abstract BigDecimal getBigDecimal(String parameterName);

	public abstract Blob getBlob(int i);

	public abstract Blob getBlob(String parameterName);

	public abstract boolean getBoolean(int parameterIndex);

	public abstract boolean getBoolean(String parameterName);

	public abstract byte getByte(int parameterIndex);

	public abstract byte getByte(String parameterName);

	public abstract byte[] getBytes(int parameterIndex);

	public abstract byte[] getBytes(String parameterName);

	public abstract Clob getClob(int i);

	public abstract Clob getClob(String parameterName);

	public abstract Date getDate(int parameterIndex, Calendar cal);

	public abstract Date getDate(int parameterIndex);

	public abstract Date getDate(String parameterName, Calendar cal);

	public abstract Date getDate(String parameterName);

	public abstract double getDouble(int parameterIndex);

	public abstract double getDouble(String parameterName);

	public abstract float getFloat(int parameterIndex);

	public abstract float getFloat(String parameterName);

	public abstract int getInt(int parameterIndex);

	public abstract int getInt(String parameterName);

	public abstract long getLong(int parameterIndex);

	public abstract long getLong(String parameterName);

	public abstract Object getObject(int i, Map<String, Class<?>> map);

	public abstract Object getObject(int parameterIndex);

	public abstract Object getObject(String parameterName,
			Map<String, Class<?>> map);

	public abstract Object getObject(String parameterName);

	public abstract Ref getRef(int i);

	public abstract Ref getRef(String parameterName);

	public abstract short getShort(int parameterIndex);

	public abstract short getShort(String parameterName);

	public abstract String getString(int parameterIndex);

	public abstract String getString(String parameterName);

	public abstract Time getTime(int parameterIndex, Calendar cal);

	public abstract Time getTime(int parameterIndex);

	public abstract Time getTime(String parameterName, Calendar cal);

	public abstract Time getTime(String parameterName);

	public abstract Timestamp getTimestamp(int parameterIndex, Calendar cal);

	public abstract Timestamp getTimestamp(int parameterIndex);

	public abstract Timestamp getTimestamp(String parameterName, Calendar cal);

	public abstract Timestamp getTimestamp(String parameterName);

	public abstract URL getURL(int parameterIndex);

	public abstract URL getURL(String parameterName);

	public abstract void registerOutParameter(int parameterIndex, int sqlType,
			int scale);

	public abstract void registerOutParameter(int paramIndex, int sqlType,
			String typeName);

	public abstract void registerOutParameter(int parameterIndex, int sqlType);

	public abstract void registerOutParameter(String parameterName,
			int sqlType, int scale);

	public abstract void registerOutParameter(String parameterName,
			int sqlType, String typeName);

	public abstract void registerOutParameter(String parameterName, int sqlType);

	public abstract boolean wasNull();

	protected abstract class NamedParameter<T> extends Parameter<T> {
		protected NamedParameter(String parameterName, T value, Object... args) {
			super(0, value, args);
			_parameterName = parameterName;
		}

		protected String _parameterName;
	}

	protected class AsciiStreamParameter extends NamedParameter<InputStream> {
		protected AsciiStreamParameter(String parameterName, InputStream value,
				int length) {
			super(parameterName, value, length);
		}

		protected void set() throws SQLException {
			_unwrap()
					.setAsciiStream(_parameterName, _value, (Integer) _args[0]);
		}
	}

	protected class BigDecimalParameter extends NamedParameter<BigDecimal> {
		protected BigDecimalParameter(String parameterName, BigDecimal value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setBigDecimal(_parameterName, _value);
		}
	}

	protected class BinaryStreamParameter extends NamedParameter<InputStream> {
		protected BinaryStreamParameter(String parameterName,
				InputStream value, int length) {
			super(parameterName, value, length);
		}

		protected void set() throws SQLException {
			_unwrap().setBinaryStream(_parameterName, _value,
					(Integer) _args[0]);
		}
	}

	protected class BooleanParameter extends NamedParameter<Boolean> {
		protected BooleanParameter(String parameterName, Boolean value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setBoolean(_parameterName, _value);
		}
	}

	protected class ByteParameter extends NamedParameter<Byte> {
		protected ByteParameter(String parameterName, Byte value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setByte(_parameterName, _value);
		}
	}

	protected class BytesParameter extends NamedParameter<byte[]> {
		protected BytesParameter(String parameterName, byte[] value,
				Object... args) {
			super(parameterName, value, args);
		}

		protected void set() throws SQLException {
			_unwrap().setBytes(_parameterName, _value);
		}
	}

	protected class CharacterStreamParameter extends NamedParameter<Reader> {
		protected CharacterStreamParameter(String parameterName, Reader value,
				int length) {
			super(parameterName, value, length);
		}

		protected void set() throws SQLException {
			_unwrap().setCharacterStream(_parameterName, _value,
					(Integer) _args[0]);
		}
	}

	protected class DateParameter extends NamedParameter<Date> {
		protected DateParameter(String parameterName, Date value) {
			super(parameterName, value);
		}

		protected DateParameter(String parameterName, Date value,
				Calendar calendar) {
			super(parameterName, value, calendar);
		}

		protected void set() throws SQLException {
			if (_args == null || _args.length == 0) {
				_unwrap().setDate(_parameterName, _value);
			} else {
				_unwrap().setDate(_parameterName, _value, (Calendar) _args[0]);
			}
		}
	}

	protected class DoubleParameter extends NamedParameter<Double> {
		protected DoubleParameter(String parameterName, Double value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setDouble(_parameterName, _value);
		}
	}

	protected class FloatParameter extends NamedParameter<Float> {
		protected FloatParameter(String parameterName, Float value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setFloat(_parameterName, _value);
		}
	}

	protected class IntParameter extends NamedParameter<Integer> {
		protected IntParameter(String parameterName, Integer value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setInt(_parameterName, _value);
		}
	}

	protected class LongParameter extends NamedParameter<Long> {
		protected LongParameter(String parameterName, Long value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setLong(_parameterName, _value);
		}
	}

	protected class NullParameter extends NamedParameter<Object> {
		protected NullParameter(String parameterName, int sqlType) {
			super(parameterName, null, sqlType);
		}

		protected NullParameter(String parameterName, int sqlType,
				String typeName) {
			super(parameterName, null, sqlType, typeName);
		}

		protected void set() throws SQLException {
			if (_args.length == 1) {
				_unwrap().setNull(_parameterName, (Integer) _args[0]);
			} else {
				_unwrap().setNull(_parameterName, (Integer) _args[0],
						(String) _args[1]);
			}
		}
	}

	protected class ObjectParameter extends NamedParameter<Object> {
		protected ObjectParameter(String parameterName, Object value) {
			super(parameterName, value);
		}

		protected ObjectParameter(String parameterName, Object value,
				int sqlType) {
			super(parameterName, value, sqlType);
		}

		protected ObjectParameter(String parameterName, Object value,
				int sqlType, int scale) {
			super(parameterName, value, sqlType, scale);
		}

		protected void set() throws SQLException {
			if (_args == null || _args.length == 0) {
				_unwrap().setObject(_parameterName, _value);
			} else if (_args.length == 1) {
				_unwrap().setObject(_parameterName, _value, (Integer) _args[0]);
			} else {
				_unwrap().setObject(_parameterName, _value, (Integer) _args[0],
						(Integer) _args[1]);
			}
		}
	}

	protected class ShortParameter extends NamedParameter<Short> {
		protected ShortParameter(String parameterName, Short value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setShort(_parameterName, _value);
		}
	}

	protected class StringParameter extends NamedParameter<String> {
		protected StringParameter(String parameterName, String value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setString(_parameterName, _value);
		}
	}

	protected class TimeParameter extends NamedParameter<Time> {
		protected TimeParameter(String parameterName, Time value) {
			super(parameterName, value);
		}

		protected TimeParameter(String parameterName, Time value,
				Calendar calendar) {
			super(parameterName, value, calendar);
		}

		protected void set() throws SQLException {
			if (_args == null || _args.length == 0) {
				setTime(_parameterName, _value);
			} else {
				setTime(_parameterName, _value, (Calendar) _args[0]);
			}
		}
	}

	protected class TimestampParameter extends NamedParameter<Timestamp> {
		protected TimestampParameter(String parameterName, Timestamp value) {
			super(parameterName, value);
		}

		protected TimestampParameter(String parameterName, Timestamp value,
				Calendar calendar) {
			super(parameterName, value, calendar);
		}

		protected void set() throws SQLException {
			if (_args == null || _args.length == 0) {
				_unwrap().setTimestamp(_parameterName, _value);
			} else {
				_unwrap().setTimestamp(_parameterName, _value,
						(Calendar) _args[0]);
			}
		}
	}

	protected class URLParameter extends NamedParameter<URL> {
		protected URLParameter(String parameterName, URL value) {
			super(parameterName, value);
		}

		protected void set() throws SQLException {
			_unwrap().setURL(_parameterName, _value);
		}
	}

	private java.sql.CallableStatement _unwrap() {
		return (java.sql.CallableStatement) unwrap();
	}

	private static final _ProxyGenerator<CallableStatement> _GENERATOR = new _ProxyGenerator<CallableStatement>(
			CallableStatement.class);

}
